import React, { useState, useEffect, useRef,RefObject } from 'react'
import debounce from 'lodash/debounce'
import './index.scss'

interface AutocompleteProps {
  getOptions: (inputValue: string) => Promise<string[]>;
  onSelect: (selectedOption: string) => void;
  debounceTime?: number;
}


const useClickOutside = (handler: () => void): RefObject<HTMLDivElement> => {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (ref.current && !ref.current.contains(event.target as Node)) {
        handler();
      }
    };

    document.addEventListener('mousedown', handleClickOutside);

    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [handler]);

  return ref;
};

const AutoComplete: React.FC<AutocompleteProps> = ({ getOptions, onSelect, debounceTime = 1000 }) => {
  const [inputValue, setInputValue] = useState<string>('');
  const [filteredOptions, setFilteredOptions] = useState<string[]>([]);
  const [isLoading, setIsLoading] = useState<boolean>(false);
  const [errorMessage, setErrorMessage] = useState<string>('');
  const handleClickOutside = () => {
    setFilteredOptions([]);
  };

  const ref = useClickOutside(handleClickOutside);


  const [value, setValue] = useState();
    const fRef = React.useRef<any>();

    const f = async () => {
      setIsLoading(true);
      setErrorMessage('');
      try {
        const options = await getOptions(inputValue);
        console.log("options", options)
        setFilteredOptions(options);
      } catch (error: any) {
        setErrorMessage(error?.message);
        setFilteredOptions([]);
      } finally {
        setIsLoading(false)
      }
    };
    fRef.current = f;

    const fn = React.useCallback(
        debounce(() => fRef.current(), debounceTime),
    [inputValue]);

  const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const value = event.target.value;
    fn()
    setInputValue(value);
  };

  const handleOptionSelect = (option: string) => {
    setInputValue(option);
    onSelect(option);
    setFilteredOptions([]);
  };


  return (
    <div className="autocomplete"  ref={ref}>
      <input type="text" value={inputValue} onChange={handleInputChange} />
      {isLoading && <div className="loading">Loading...</div>}
      {errorMessage && <div className="error">{errorMessage}</div>}
    {filteredOptions.length > 0 && (
      <div className="options">
        {filteredOptions.map((option) => (
          <div key={option} className="option" onClick={() => handleOptionSelect(option)}>
            {option}
          </div>
        ))}
      </div>
    )}
  </div>
  )
}

export default AutoComplete
